package com.example.block_chain.service.impl.student;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.block_chain.RabbitMQ.Producer;
import com.example.block_chain.common.AppHttpCodeEnum;
import com.example.block_chain.common.ResponseResult;
import com.example.block_chain.common.SystemParameters;
import com.example.block_chain.domain.pbft.VoteInfo;
import com.example.block_chain.domain.pojo.Student;
import com.example.block_chain.mapper.StudentMapper;
import com.example.block_chain.service.blockChain.BlockService;
import com.example.block_chain.service.student.StudentService;
import com.example.block_chain.utils.node.PostRequestUtil;
import com.example.block_chain.utils.node.StudentNodePostBody;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@Service
@Slf4j
public class StudentServiceImpl implements StudentService {

    @Autowired
    private StudentMapper studentMapper;

    @Resource
    BlockService blockService;

    @Resource
    Producer producer;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public ResponseResult allMessage(String studentId) {
        Student student = studentMapper.selectById(studentId);

        return ResponseResult.okResult(student);
    }

    @Override
    public ResponseResult handleFileUpload(MultipartFile awardFile, HttpSession session) {
        if (awardFile.isEmpty()) {
            return ResponseResult.errorResult(500, "文件内容为空");
        }

        Student student = (Student) session.getAttribute("student");


        System.out.println(student);
        /**
         * 这里awardUrl待使用打开网址
         */
        String awardUrl = "http";
        /*//添加数据库表award字段：digest后报错：注释了
        Award award = new Award(null,student.getSNo(),student.getANo(),awardUrl,0,student.getClassCode(),
                student.getMajorCode(),student.getFacultyCode(),student.getSchoolCode(),null,null,new Date());
        awardMapper.insert(award);
*/
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult batchCreateStudents(MultipartFile file) {
        List<Student> students = new ArrayList<>();
        try (Workbook workbook = new XSSFWorkbook(file.getInputStream())) {
            Sheet sheet = workbook.getSheetAt(0); // 假设数据在第一个sheet中

            Iterator<Row> rowIterator = sheet.iterator();
            rowIterator.next();
            while (rowIterator.hasNext()) {
                Row row = rowIterator.next();
                Iterator<Cell> cellIterator = row.cellIterator();

                Student student = new Student();
                boolean ok = false;
                for (int i = 0; i <= 10; i++) {
                    if (row.getCell(i) == null) {
                        ok = true;
                        continue;
                    }
                    if (row.getCell(i).getCellType() == CellType.NUMERIC) {
                        double tmp_value = row.getCell(i).getNumericCellValue();
                        int value = (int) tmp_value;
                        setStudent(i, Integer.toString(value), student);
                    } else if (row.getCell(i).getCellType() == CellType.STRING) {
                        String value = row.getCell(i).getStringCellValue();
                        setStudent(i, value, student);
                        System.out.println(value);
                    }
                }
                if (ok) continue;
                //增加区块链学生节点
                if (!haveStudent(student.getSNo())) {
                    students.add(student);
                    //保存学生到数据库
                    studentMapper.insert(student);

                    VoteInfo studentBlock = blockService.createStudentBlock(student.getSNo(), student.getSchoolCode(), student.getMajorCode());
                    producer.sendMessage(studentBlock);
                } else log.error(AppHttpCodeEnum.CODE_EXISTS.toString());
            }
            //批量增加图数据库学生节点
            List<StudentNodePostBody> nodes = PostRequestUtil.getStudentNodes(students);
            PostRequestUtil.sendBatchSaveStudentPostRequest(SystemParameters.TARGET_URL, nodes);

            workbook.close();
            return ResponseResult.okResult();
        } catch (IOException e) {
            return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR);
        }
    }

    private boolean haveStudent(String sNo) {
        QueryWrapper<Student> wrapper = new QueryWrapper<>();
        wrapper.eq("s_no", sNo);
        Student student = studentMapper.selectOne(wrapper);
        return student != null;
    }


    private void setStudent(int i, String value, Student student) {
        switch (i) {
            case 0:
                student.setSNo(value);
                break;
            case 1:
                student.setSName(value);
                break;
            case 2:
                student.setSSex(value);
                break;
            case 3:
                student.setSID(value);
                break;
            case 4:
                student.setANo(value);
                break;
            case 5:
                student.setClassCode(value);
                break;
            case 6:
                student.setMajorCode(value);
                break;
            case 7:
                student.setFacultyCode(value);
                break;
            case 8:
                student.setSchoolCode(value);
                break;
            case 9:
                student.setSGrade(value);
                break;
            case 10:
                student.setSPassword(passwordEncoder.encode(value));
                break;
            default:
                break;
        }
    }
}
